#include "Base.h"
#include "ClientPool.h"
#include "Log.h"
#include "Lock.h"

CClientPool::CClientPool()
{
	memset(m_pClients, 0, sizeof(m_pClients));
	m_nTotalCount = 0;
	m_nFreeCount = 0;
	m_nRunCount = 0;

	Tick();
}

CClientPool::~CClientPool()
{
	for(int i = 0; i < m_nTotalCount; i++)
	{
		SAFE_DELETE(m_pClients[i]);
	}
}

void CClientPool::Tick()
{
	CAutoLock autoLock(m_lock);
	while(m_nFreeCount < Init_Client_Count && m_nTotalCount < Max_Client_Count)
	{
		AllocateOne();
	}
}

void CClientPool::AllocateOne()
{
	CClient *pClient = new CClient();
	if(pClient == NULL)
	{
		WriteLog("%s:%d,AllocateOne Fail!",__FILE__, __LINE__);
		return;
	}
	pClient->SetClientId(m_nTotalCount);
	m_pClients[m_nTotalCount++] = pClient;
	m_listFreeClient.push_back(pClient);
	m_nFreeCount++;
}

CClient* CClientPool::CreateClient()
{
	CAutoLock autoLock(m_lock);
	if(m_nFreeCount <= 0)
	{
		if(m_nTotalCount < Max_Client_Count)
		{
		    AllocateOne();
		}
		else
		{
			WriteLog("%s:%d,CreateClient Failure, Reach Max_Client_Count!",__FILE__, __LINE__);
			return NULL;
		}
	}
	CClient *pClient = *m_listFreeClient.begin();
	if(pClient == NULL)
	{
		WriteLog("%s:%d,CreateClient Failure, m_listFreeClient.being() is NULL!",__FILE__, __LINE__);
		return NULL;
	}
	m_listFreeClient.pop_front();
	m_nFreeCount--;
	m_listRunClient.push_front(pClient);
	pClient->m_iteratorClient = m_listRunClient.begin();
	m_nRunCount++;
	pClient->m_bFree = FALSE;
	return pClient;
}

void CClientPool::ReleaseClient(CClient *pClient)
{
	if(pClient->m_bFree)
		return;
	CAutoLock autoLock(m_lock);
	m_listFreeClient.push_back(pClient);
	m_nFreeCount++;
	m_listRunClient.erase(pClient->m_iteratorClient);
	m_nRunCount--;
	pClient->Reset();
	//WriteLog("CClientPool::ReleaseClient %0x,%d", (DWORD)pClient, pClient->GetClientId());
}